﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace MCYFlashApp
{
    public class PlayControl
    {
        private string _exePro = "effect";
        private string _starBat = "star.cmd";
        private int _playTime = 1;
        public int PlayTime { set { _playTime = value; } get { return _playTime; } }

        public List<SwfFile> AutoPlayFiles { set; get; }

        FrmSwf _temFrmSwf;

        private int _currentIndex = 0;
        private Timer _timer;
        private bool _IsAuto = true;

        //private bool _isPlaying = false;


        [DllImport("user32.dll", SetLastError = true)]
        static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        static extern bool EndDialog(IntPtr hDlg, out IntPtr nResult);
        public const int WM_CLOSE = 0x10;

        [DllImport("user32.dll", EntryPoint = "SendMessageA")]
        public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);

        [DllImport("user32.dll")]
        public static extern void SwitchToThisWindow(IntPtr hWnd, bool fAltTab);


        /// <summary>
        /// 委托必须和要调用的异步方法有相同的签名
        /// </summary>
        /// <param name="callDuration">sleep时间</param>
        /// <param name="threadId">当前线程id</param>
        /// <returns></returns>
        public delegate void AsyncMethodCaller();


        public PlayControl()
        {
            AutoPlayFiles = new List<SwfFile>();
            _timer = new Timer();
            _timer.Tick += _timer_Tick;

        }




        #region Event
        private void _timer_Tick(object sender, EventArgs e)
        {
            if (!_IsAuto) return;

            _currentIndex++;
            if (_currentIndex >= AutoPlayFiles.Count)
                _currentIndex = 0;

            PlaySwfFile(AutoPlayFiles[_currentIndex]);

            _timer.Start();
        }

        private void swf_Disposed(object sender, EventArgs e)
        {
            _timer.Enabled = false;
        }
        #endregion


        #region Method
        public void KillPer()
        {
            KillExe();
            KillSwf();
        }

        public void AutoPlay(List<SwfFile> files)
        {

            if (files.Count == 0)
                return;

            _IsAuto = true;
            _timer.Enabled = true;
            _timer.Interval = _playTime * 60 * 1000;
            //_timer.Interval = 30 * 1000;
            AutoPlayFiles = files.OrderBy(p => p.Index).ToList();
            _currentIndex = 0;

            PlaySwfFile(AutoPlayFiles[_currentIndex]);
            _timer.Start();

        }

        public void PlayFile(SwfFile file, bool isAuto = false)
        {
            _IsAuto = isAuto;
            _timer.Enabled = isAuto;
            _currentIndex = file.Index;
            if (_IsAuto)
            {
                _timer.Interval = _playTime * 60 * 1000;

                _timer.Start();
            }
            PlaySwfFile(file);
        }

        public void PlayBefor()
        {
            if (AutoPlayFiles.Count == 0)
                return;
            if (_IsAuto)
            {
                _timer.Stop();
                _timer.Enabled = false;

            }
            if (_currentIndex == 0)
            {
                _currentIndex = AutoPlayFiles.Count - 1;
            }
            else
            {
                _currentIndex--;
            }

            PlaySwfFile(AutoPlayFiles[_currentIndex]);
            if (_IsAuto)
            {
                _timer.Enabled = true;
                _timer.Start();
            }
        }

        public void PlayAfter()
        {
            if (AutoPlayFiles.Count == 0)
                return;
            if (_IsAuto)
            {
                _timer.Stop();
                _timer.Enabled = false;

            }
            if (_currentIndex == AutoPlayFiles.Count - 1)
            {
                _currentIndex = 0;
            }
            else
            {
                _currentIndex++;
            }

            PlaySwfFile(AutoPlayFiles[_currentIndex]);
            if (_IsAuto)
            {
                _timer.Enabled = true;
                _timer.Start();
            }
        }
        #endregion

        private void PlaySwfFile(SwfFile file)
        {
            try
            {

                if (file.FileExtension.ToLower().Contains("exe"))
                {
                    KillPer();

                    int last = file.FilePath.LastIndexOf("\\");
                    string dirPath = file.FilePath.Substring(0, last);
                    string exeName = file.FilePath.Replace(dirPath, "").Replace("\\", "");
                    StarWithBat(dirPath, exeName);

                    SetBefore(exeName.Replace(".exe", ""));

                }
                else
                {
                    KillExe();
                    if (_temFrmSwf == null || _temFrmSwf.IsDisposed)
                    {
                        _temFrmSwf = new FrmSwf();
                        _temFrmSwf.Disposed += swf_Disposed;
                        _temFrmSwf.Show();
                    }
                    _temFrmSwf.Activate();
                    _temFrmSwf.BringToFront();
                    _temFrmSwf.SetFile(file.FilePath);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void KillSwf()
        {
            IntPtr dlg = FindWindow(null, "Frmswf");
            if (dlg != IntPtr.Zero)
            {
                SendMessage(dlg, WM_CLOSE, 0, 0);
            }
        }

        private void KillCmd()
        {
            Process[] processes = Process.GetProcessesByName("cmd");
            if (processes.Length > 0)
            {
                for (int i = 0; i < processes.Length; i++)
                {
                    try
                    {
                        processes[i].Kill();
                    }
                    catch (Exception)
                    {

                    }
                }
            }
        }

        private void CallMethodAsync()
        {
            _temFrmSwf.Close();
        }

        private void KillExe()
        {
            string[] exePro = ConfigureAppConfig.GetAppSettingsKeyValue("ExePro").Split(',');
            for (int x = 0; x < exePro.Length; x++)
            {
                if (string.IsNullOrWhiteSpace(exePro[x]))
                    continue;
                Process[] processes = Process.GetProcessesByName(exePro[x]);
                if (processes.Length > 0)
                {
                    for (int i = 0; i < processes.Length; i++)
                    {
                        try
                        {
                            processes[i].Kill();
                        }
                        catch (Exception)
                        {

                        }
                    }
                }
            }
        }
        /// <summary>
        /// 设置程序前置，，不包含exe
        /// </summary>
        /// <param name="strName"></param>
        private void SetBefore(string strName)
        {
            Process[] processes = Process.GetProcessesByName(strName);
            if (processes.Length > 0)
            {
                for (int i = 0; i < processes.Length; i++)
                {
                    try
                    {
                        IntPtr handle = processes[0].MainWindowHandle;
                        SwitchToThisWindow(handle, true);    // 激活，显示在最前   
                    }
                    catch (Exception)
                    {

                    }
                }
            }
        }

        private void StarWithBat(string filePath, string exeNme)
        {
            //先创建BAT文件
            CreatStarBat(filePath, exeNme);
            InsertIntoConfig(exeNme);
            Process proc = new Process();
            proc.StartInfo.WorkingDirectory = filePath;
            proc.StartInfo.FileName = "star.cmd";
            //proc.StartInfo.Arguments = string.Format("10");//this is argument
            proc.StartInfo.CreateNoWindow = false;
            proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//这里设置DOS窗口不显示，经实践可行
            proc.Start();


            //proc.WaitForExit();
            System.Threading.Thread.Sleep(2000);
            KillCmd();
        }

        private void CreatStarBat(string filePath, string exeName)
        {
            string fileName = Path.Combine(filePath, _starBat);
            if (File.Exists(fileName))
                return;
            FileStream fs = File.Create(fileName);
            byte[] data = System.Text.Encoding.Default.GetBytes(exeName);
            fs.Write(data, 0, data.Length);
            fs.Flush();
            fs.Close();
        }
        /// <summary>
        /// 写配置文件
        /// </summary>
        /// <param name="exeName"></param>
        private void InsertIntoConfig(string exeName)
        {
            if (ConfigureAppConfig.GetAppSettingsKeyValue("ExePro").Contains(exeName.Replace(".exe", "")))
                return;
            string newstr = ConfigureAppConfig.GetAppSettingsKeyValue("ExePro") + "," + exeName.Replace(".exe", "");
            ConfigureAppConfig.AppSettingsSave("ExePro", newstr);
        }

        /// <summary>
        /// 通过CMD命令启动程序
        /// </summary>
        /// <param name="filePath"></param>
        private void StarWithCmd(string filePath)
        {

            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.CreateNoWindow = false;
            p.Start();
            //向cmd.exe输入command 
            // p.StandardInput.WriteLine("cd C:\\Inetpub\\wwwroot\\Paicdom\\PaWebService\\PaWeb\\Manage\\Exportcsv");
            //cmd又调用了ociuldr.ex
            // p.StandardInput.WriteLine("ociuldr.exe");
            p.StandardInput.WriteLine(filePath);
            p.StandardInput.WriteLine("exit"); //需要有这句，不然程序会挂机
            //string output = p.StandardOutput.ReadToEnd(); 这句可以用来获取执行命令的输出结果
        }

        private void StarWithCmd2(string filePath)
        {
            System.Diagnostics.Process p = new System.Diagnostics.Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = true;    //是否使用操作系统shell启动
            p.StartInfo.RedirectStandardInput = true;//接受来自调用程序的输入信息
            p.StartInfo.RedirectStandardOutput = true;//由调用程序获取输出信息
            p.StartInfo.RedirectStandardError = true;//重定向标准错误输出
            p.StartInfo.CreateNoWindow = true;//不显示程序窗口

            p.Start();//启动程序

            //向cmd窗口发送输入信息
            p.StandardInput.WriteLine(filePath);
            p.WaitForExit();//等待程序执行完退出进程
            p.Close();
        }

        /// <summary>
        /// 使用进程启动程序
        /// </summary>
        /// <param name="strPath"></param>
        /// <param name="args"></param>
        private void StarProcess(string strPath, string args)
        {
            ProcessStartInfo info = new ProcessStartInfo();
            info.FileName = strPath;
            info.Arguments = args;
            info.WindowStyle = ProcessWindowStyle.Maximized;
            Process pro = Process.Start(info);
            pro.Start();
        }
    }
}
